*&--------------------------------------------------------------------*
*& Include ZALVFLIGHT_CLASSES                                         *
*&--------------------------------------------------------------------*
class lcl_flight_model definition.
   public section.
      types: ty_flight_list type standard table
                              of bapisfldat,
             ty_date_range  type standard table
                              of bapisfldra.

      methods:
         query_flights
            importing im_from        type s_airport
                      im_depart_date type s_date
                      im_to          type s_airport
                      im_return_date type s_date.

      data: flight_list type ty_flight_list.
endclass.

class lcl_flight_model implementation.
   method query_flights.
*     Method-Local Data Declarations:
      data: ls_from_dest  type bapisfldst,
            ls_to_dest    type bapisfldst,
            lt_date_range type ty_date_range.
      field-symbols:
         <lfs_date_range> like line of lt_date_range.

*     Populate the from/to destination structures:
      ls_from_dest-airportid = im_from.
      ls_to_dest-airportid = im_to.

*     Build the selection date range - as necessary:
      if not im_depart_date is initial.
         append initial line to lt_date_range
                      assigning <lfs_date_range>.
         <lfs_date_range>-low = im_depart_date.

         if not im_return_date is initial.
            <lfs_date_range>-sign   = 'I'.
            <lfs_date_range>-option = 'BT'.
            <lfs_date_range>-high   = im_return_date.
         else.
            <lfs_date_range>-sign   = 'I'.
            <lfs_date_range>-option = 'EQ'.
         endif.
      endif.

*     Use the standard BAPI to perform the flight query:
      call function 'BAPI_FLIGHT_GETLIST'
         exporting
            destination_from = ls_from_dest
            destination_to   = ls_to_dest
         tables
            date_range       = lt_date_range
            flight_list      = flight_list.

   endmethod.
endclass.

class lcl_planner_ctrl definition.
   public section.
      methods:
         constructor,
         do_display_report
            importing im_from        type s_airport
                      im_depart_date type s_date
                      im_to          type s_airport
                      im_return_date type s_date,
         on_double_click for event double_click
                                of cl_salv_events_table
                         importing row
                                   column.
   private section.
      data: lr_flight_model type ref to lcl_flight_model,
            lr_grid         type ref to cl_salv_table.

      methods:
         show_grid.
endclass.

class lcl_planner_ctrl implementation.
   method constructor.
*     Inititalize the flight model:
      create object lr_flight_model.
   endmethod.

   method do_display_report.
*     Use the model method "QUERY_FLIGHTS" to query the
*     flight database:
      call method lr_flight_model->query_flights
         exporting
            im_from        = im_from
            im_depart_date = im_depart_date
            im_to          = im_to
            im_return_date = im_return_date.

*     Display the result set in an ALV grid:
      show_grid( ).
   endmethod.

   method on_double_click.
*     Method-Local Data Declarations:
      data: ls_selected_flight type bapisfldat,
            ls_flight_info     type sflight,
            lv_open_seats      type numc5,
            lv_message         type string.

*     Read the selected flight record from the model
*     using the "row" index provided by the event:
      read table lr_flight_model->flight_list
           index row
            into ls_selected_flight.

*     Use the key of the selected flight record to extract
*     additional flight information from table SFLIGHT:
      select single *
        into ls_flight_info
        from sflight
       where carrid eq ls_selected_flight-airlineid
         and connid eq ls_selected_flight-connectid
         and fldate eq ls_selected_flight-flightdate.

*     Calculate the total number of available seats left
*     on the flight:
      lv_open_seats =
        ls_flight_info-seatsmax - ls_flight_info-seatsocc.
      shift lv_open_seats left deleting leading '0'.
      shift ls_flight_info-connid left deleting leading '0'.

*     Display the results in a popup message:
      concatenate 'There are'(001)
                  lv_open_seats
                  'seats available on Flight'(002)
                  ls_flight_info-connid
             into lv_message
        separated by space.

      message lv_message type 'I'.
   endmethod.

   method show_grid.
*     Method-Local Data Declarations:
      data: lr_functions type ref to cl_salv_functions,
            lr_display   type ref to cl_salv_display_settings,
            lr_events    type ref to cl_salv_events_table.

*     Use the factory method to create an instance of the ALV grid:
      try.
         call method cl_salv_table=>factory
            importing
               r_salv_table = lr_grid
            changing
               t_table      = lr_flight_model->flight_list.
     catch cx_salv_msg.
     endtry.

*    Enable the standard ALV toolbar:
     lr_functions = lr_grid->get_functions( ).
     lr_functions->set_all( abap_true ).

*    Adjust the display settings on the grid:
     lr_display = lr_grid->get_display_settings( ).
     lr_display->set_fit_column_to_table_size( ).

*    Register the event handler method "ON_DOUBLE_CLICK" so
*    that we can respond to double-click events on the grid:
     lr_events = lr_grid->get_event( ).
     set handler me->on_double_click for lr_events.

*    Display the ALV grid:
     lr_grid->display( ).
   endmethod.
endclass.